package org.fqh.common.velocity;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.PrintWriter;
import java.io.UnsupportedEncodingException;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;

import org.apache.commons.lang.StringUtils;
import org.apache.velocity.Template;
import org.apache.velocity.VelocityContext;
import org.apache.velocity.app.VelocityEngine;
import org.apache.velocity.runtime.RuntimeConstants;
import org.apache.velocity.runtime.resource.loader.ClasspathResourceLoader;
import org.fqh.common.utils.FileCreateUtil;
import org.fqh.common.utils.MyStringUtils;
import org.junit.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
* @author fqh 
* @version 创建时间：2017年11月30日 下午5:49:37
* 类说明: 代码生成 器    
*/
public class TemplateGenerator{
	
	private final static Logger logger=LoggerFactory.getLogger(TemplateGenerator.class);
	 
	
	 @Test
	 public void test() {
		   String tableName = "t_sys_organization";
		   String tablepackage= "org.fqh.system";
		   geratorByTable(tableName,tablepackage);
	 }
 
	 /**
	  *  
	  * @param tableName 数据库的表名
	  * @param tablepackage 放的包位置
	  */
	 public static void geratorByTable(String tableName,String tablepackage) {
		  Map  tableStructs = GetTableStructs.getTableStruct(tableName);
		   Map<String,String> templatePath = new HashMap<>();
		   templatePath.put("template/entityTemplate.vm", "\\src\\main\\java\\org\\fqh\\system\\entity\\MODEL.java");//生成model 
		   templatePath.put("template/daoTemplate.vm", "\\src\\main\\java\\org\\fqh\\system\\dao\\MODELDao.java");//生成Dao层
		   templatePath.put("template/xmlTemplate.vm", "\\src\\main\\resources\\mybatis\\mapper\\MODELMapper.xml");//生成mpper  
		   templatePath.put("template/serviceTemplate.vm", "\\src\\main\\java\\org\\fqh\\system\\service\\MODELService.java");//生成service
		   templatePath.put("template/serviceImplTemplate.vm", "\\src\\main\\java\\org\\fqh\\system\\service\\impl\\MODELServiceImpl.java");//生成service
		  // templatePath.put("template/actionTemplate.vm", "\\src\\main\\java\\org\\fqh\\system\\service\\MODELAction.java");//生成action
		   Generator(tableName,tableStructs, templatePath,"org.fqh.system");
		 
	 }
	
	  /**
	   * 生成代码 
	   * @param tableName  表名 
	   * @param tableStructs 表结构 
	   * @param templatePath   map<模版路径,生成文件路径+名称>
	   */
	   public static  void Generator(String tableName,Map<String,String> tableStructs,Map<String,String> templatePath,String tablepackage) {
			 VelocityEngine ve = new VelocityEngine();
			 ve.setProperty(RuntimeConstants.RESOURCE_LOADER, "classpath");
			 ve.setProperty("classpath.resource.loader.class", ClasspathResourceLoader.class.getName());
			  
			 ve.init();
			 
			 VelocityContext ctx = new VelocityContext();
             String modelName = MyStringUtils.getStringTableColumn(tableName,true);
             ctx.put("modelName", modelName); //模型名称 
			 ctx.put("tableName", tableName); //表名
			 ctx.put("tablepackage", tablepackage); //名称
			 Map<String,String> importPackage = new HashMap<String,String>();
			 Map<String,String> tableCols = new HashMap<String,String>();  // 表-对应实体类结构
			 Map<String,String> tableStructs1 = new HashMap<String,String>();  // 表-对应实体类结构
			 for (String key : tableStructs.keySet()) {
				  
				   String value =  tableStructs.get(key);
				   if(judgeIsNotBasic(value)) {
					   importPackage.put(value,value);  
				   }
				   if( value.contains(".")) {
					   value =StringUtils.substringAfterLast(value,".");
				   }
				   tableStructs.put(key,value);
				   tableCols.put(MyStringUtils.underline2Camel(key,true), key);
				   tableStructs1.put(MyStringUtils.underline2Camel(key,true),value);
		     }
			 ctx.put("importPackage", importPackage);
			 ctx.put("tableStructs", tableStructs); 
			 ctx.put("tableStructs1", tableStructs1);
			 ctx.put("tableCols",tableCols);
			 DateFormat format= new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");  
			 ctx.put("Time", format.format(new Date()));  //时间 
			 String rootPath =System.getProperty("user.dir") ; 
			 Set<Entry<String, String>> entrySet = templatePath.entrySet();
			
			for (Entry<String, String> entry : entrySet) {
				Template t = ve.getTemplate(entry.getKey());
				String path = entry.getValue(); 
			    path = path.replaceAll("MODEL",modelName);
			    logger.info("生成文件路径:"+rootPath + path); 

		        File file = new File(rootPath + path);
		        FileCreateUtil.judeFileExists(file); //判断 文件是否存在 
		        FileCreateUtil.judeDirExists(new File(file.getParent()));   
			    merge(t,ctx,rootPath +path);
		        logger.info(path+"文件生成成功...");
					 
			}
			 
		 }
		 private static void merge(Template template, VelocityContext ctx, String path) {
			 PrintWriter writer = null; 
			 try {
		
				 writer = new PrintWriter(path); 
				 template.merge(ctx, writer);
				 writer.flush();
			 } catch (FileNotFoundException e) {
				 e.printStackTrace();
			 } finally {
				 writer.close();
			 }
		 }
		 /**
		  * 判断是否为基本的类型,不需要引入jar包 
		  * @param value
		  * @return
		  */
		 private static boolean judgeIsNotBasic(String value) {
			 ArrayList<String> list = new ArrayList<String>();	 
			 list.add( "java.math.BigInteger");
			 list.add( "java.math.BigDecimal");
			 list.add( "java.util.Date");
			 list.add( "java.sql.Time");
			 list.add( "java.sql.Timestamp");
			 list.add( "java.sql.Timestamp");
			 list.add( "java.sql.Date");
			 
			 if(list.contains(value)) {
				 return true;
			 }else {
				 return false;	 
			 }
			 
		
		 }
	}